package io.mft.plugin;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import io.mft.commons.exception.MFTException;
import io.mft.commons.function.ExecuteReturn;
import lombok.Getter;

@Getter
public class PluginFunctionExecutor<T>{
	static Logger logger=LoggerFactory.getLogger(PluginFunctionExecutor.class);
	public final static ThreadLocal<String> THREADLOCAL_VERSION=new ThreadLocal<>();
	private PluginFunction<T> function;
	private String version;
	private ClassLoader pluginClassLoader;
	public PluginFunctionExecutor(PluginFunction<T> function,String version,ClassLoader pluginClassLoader) {
		this.function=(PluginFunction<T>)function;
		this.version=version;
		this.pluginClassLoader=pluginClassLoader;
	}
	public ExecuteReturn doExecute(PluginContext<T> context) {
		ClassLoader contextClassLoader=Thread.currentThread().getContextClassLoader();
		try {
			THREADLOCAL_VERSION.set(version);
			Thread.currentThread().setContextClassLoader(pluginClassLoader);
			
			ExecuteReturn executeReturn=function.doExecute(context);
			if (executeReturn.getCode()!=0) {
				context.getResponse().setErrorNo(executeReturn.getCode());
				context.getResponse().setErrorInfo(executeReturn.getMessage());
				context.getResponse().clear();
			}else if (context.getResponse().getErrorNo()!=0) {
				context.getResponse().clear();
				executeReturn=ExecuteReturn.builder().code(context.getResponse().getErrorNo()).message(context.getResponse().getErrorInfo()).build();
			}
			return executeReturn;
		} catch (Throwable e) {
			throw new MFTException(e);
		}finally {
			try {
				Thread.currentThread().setContextClassLoader(contextClassLoader);
				THREADLOCAL_VERSION.remove();				
			} catch (Exception e2) {
				logger.error("",e2);
			}

		}
	}
}
